﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MvcEngine.Blog.Repositories;
using MvcEngine.Blog.Models.Entities;
using MvcEngine.LinqToSqlProvider;
using MvcEngine.Core.Pagination;

namespace MvcEngine.Blog.LinqToSqlProvider
{
    public class BlogTagRepository : Repository, IBlogTagRepository
    {
        public IList<KeyValuePair<BlogTag, int>> GetTagsWithPostCount(Guid blogId)
        {
            using (var contextManager = CreateContextManager(true))
            {
                return (from c in contextManager.Context.Tags()
                        join pt in contextManager.Context.PostTags() on c.Id equals pt.TagId
                        join p in contextManager.Context.Posts() on pt.PostId equals p.Id
                        where c.BlogId == blogId && p.PublishedDate.HasValue
                        orderby c.CreatedDate
                        group c by new { Name = c.Name, c.Slug, c.BlogId } into res
                        select new KeyValuePair<BlogTag, int>(
                        new BlogTag
                        {
                            BlogId = res.Key.BlogId,
                            Slug = res.Key.Slug,
                            Name = res.Key.Name
                        }, res.Count())).ToList();
            }
        }

        public void Add(BlogTagBase entity)
        {
            using (var contextManager = CreateContextManager(false))
            {
                contextManager.Context.Tags().InsertOnSubmit(entity);
                contextManager.Commit();
            }
        }

        public BlogTagBase Get(Guid id)
        {
            using (var contextManager = CreateContextManager(true))
            {
                return contextManager.Context.Tags().SingleOrDefault(c => c.Id == id);
            }
        }

        public void Delete(Guid id)
        {
            using (var contextManager = CreateContextManager(false))
            {
                var tag = contextManager.Context.Tags().SingleOrDefault(c => c.Id == id);
                if (tag != null)
                {
                    contextManager.Context.Tags().DeleteOnSubmit(tag);
                    contextManager.Commit();
                }
            }
        }

        public void DeleteAll(Guid blogId)
        {
            throw new NotImplementedException();
        }

        public IList<BlogTagBase> GetAll(Guid blogId)
        {
            using (var contextManager = CreateContextManager(true))
            {
                return (from c in contextManager.Context.Tags()
                        where c.BlogId == blogId
                        select c).ToList();
            }
        }

        public BlogTagBase Get(Guid blogId, string tagSlug)
        {
            using (var contextManager = CreateContextManager(true))
            {
                return contextManager.Context.Tags().SingleOrDefault(c => c.BlogId == blogId && c.Slug == tagSlug);
            }
        }

        public IPagination<BlogTagBase> GetAll(Guid blogId, int pageNumber, int pageSize)
        {
            using (var contextManager = CreateContextManager(true))
            {
                return (from c in contextManager.Context.Tags()
                        where c.BlogId == blogId
                        select c).AsPagination(pageNumber, pageSize);
            }
        }

        public IList<BlogTagBase> GetAllByPost(Guid postId)
        {
            using (var contextManager = CreateContextManager(true))
            {
                return (from c in contextManager.Context.Tags()
                        join pt in contextManager.Context.PostTags() on c.Id equals pt.TagId
                        join p in contextManager.Context.Posts() on pt.PostId equals p.Id
                        where p.Id == postId
                        orderby c.CreatedDate
                        select c).ToList();
            }
        }

        public void Update(BlogTagBase tagToSave)
        {
            using (var contextManager = CreateContextManager(false))
            {
                contextManager.Commit();
            }
        }
    }
}
